return in_possession;
}
+
+/* Clear stream-id from all UI devices that reference the stream that lost all ports */
+static void
+clear_stream_from_devices (GvcMixerControl *control,
+ GvcMixerStream *stream)
+{
+ g_autoptr (GList) devices = NULL;
+ guint stream_id;
+
+ stream_id = gvc_mixer_stream_get_id (stream);
+ devices = g_hash_table_get_values (GVC_IS_MIXER_SOURCE (stream) ? control->priv->ui_inputs : control->priv->ui_outputs);
+
+ for (GList *d = devices; d != NULL; d = d->next) {
+ guint device_stream_id;
+ GvcMixerUIDevice *device = d->data;
+
+ g_object_get (G_OBJECT (device),
+ "stream-id", &device_stream_id,
+ NULL);
+
+ if (device_stream_id == stream_id) {
+ g_object_set (G_OBJECT (device),
+ "stream-id", GVC_MIXER_UI_DEVICE_INVALID,
+ NULL);
+ g_debug ("Clearing stream-id: %d", stream_id);
+ }
+ }
+}
+
/*
* This method attempts to match a sink or source with its relevant UI device.
* GvcMixerStream can represent both a sink or source.
*/
static void
sync_devices (GvcMixerControl *control,
- GvcMixerStream* stream)
+ GvcMixerStream* stream,
+ gboolean is_bluetooth)
{
/* Go through ports to see what outputs can be created. */
const GList *stream_ports;
stream_ports = gvc_mixer_stream_get_ports (stream);
+ if (stream_ports == NULL && is_bluetooth) {
+ clear_stream_from_devices (control, stream);
+ return;
+ }
+
if (stream_ports == NULL) {
GvcMixerUIDevice *device;
GObject *object;
}
}
+static gboolean
+is_bluetooth (const pa_proplist *proplist)
+{
+ const char *bus = pa_proplist_gets (proplist, "device.bus");
+
+ if (bus == NULL)
+ return FALSE;
+
+ if (g_str_equal ("bluetooth", bus))
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Called when anything changes with a sink.
*/
GvcChannelMap *map;
char map_buff[PA_CHANNEL_MAP_SNPRINT_MAX];
GList *list = NULL;
+ gboolean is_bt;
pa_channel_map_snprint (map_buff, PA_CHANNEL_MAP_SNPRINT_MAX, &info->channel_map);
#if 1
gvc_mixer_stream_set_base_volume (stream, (guint32) info->base_volume);
gvc_mixer_stream_set_state (stream, translate_pa_state (info->state));
+ is_bt = is_bluetooth (info->proplist);
/* Sync devices as the port on the stream might have changed */
if (!is_new)
- sync_devices (control, stream);
+ sync_devices (control, stream, is_bt);
/* Messy I know but to set the port everytime regardless of whether it has changed will cost us a
* port change notify signal which causes the frontend to resync.
add_stream (control, stream);
/* Always sync on a new stream to able to assign the right stream id
* to the appropriate outputs (multiple potential outputs per stream). */
- sync_devices (control, stream);
+ sync_devices (control, stream, is_bt);
} else {
g_signal_emit (G_OBJECT (control),
signals[STREAM_CHANGED],
gvc_channel_map_volume_changed (map, &info->volume, FALSE);
}
+
static void
update_source (GvcMixerControl *control,
const pa_source_info *info)
gboolean is_new;
pa_volume_t max_volume;
GList *list = NULL;
+ gboolean is_bt;
#if 1
g_debug ("Updating source: index=%u name='%s' description='%s'",
gvc_mixer_stream_set_base_volume (stream, (guint32) info->base_volume);
g_debug ("update source");
+ is_bt = is_bluetooth (info->proplist);
/* Sync devices as the port on the stream might have changed */
if (!is_new)
- sync_devices (control, stream);
+ sync_devices (control, stream, is_bt);
if (info->active_port != NULL) {
if (is_new)
GUINT_TO_POINTER (info->index),
g_object_ref (stream));
add_stream (control, stream);
- sync_devices (control, stream);
+ sync_devices (control, stream, is_bt);
} else {
g_signal_emit (G_OBJECT (control),
signals[STREAM_CHANGED],